package com.mszlu.blog.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mszlu.blog.dao.mapper.ArticleMapper;
import com.mszlu.blog.dao.pojo.Article;
import com.mszlu.blog.utils.IpUtils;
import com.mszlu.blog.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: lfw
 * @Date: 2022/03/25/17:25
 * @Description:
 */
@Component
public class ThreadService {

    private static final String QUESTION_KEY = "View:";
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ArticleMapper mapper;
    //期望此操作在线程池执行不会影响原有主线程
    private  static Map<String,Integer> map=new HashMap<>();
    @Async("taskExecutor")
    public void updateArticleViewCount(Article article) {
        int increment = redisTemplate.boundValueOps(QUESTION_KEY + article.getId()).increment().intValue();
        map.put(QUESTION_KEY + article.getId(),increment);
    }
    @Scheduled(cron ="0 0 0 * * *")
    public void sayHello() {
        Set<String> keySet = map.keySet();
        if (!keySet.isEmpty()){
                for (String s : keySet) {
                    String articleId=s.substring(5);
                    Article article = mapper.selectById(articleId);
                    int viewCounts = article.getViewCounts();
                    Article articleupdate = new Article();
                    articleupdate.setViewCounts(viewCounts+map.get(s));
                    System.out.println(articleupdate);
                    LambdaQueryWrapper<Article> underwater = new LambdaQueryWrapper<>();
                    underwater.eq(Article::getId, article.getId());
                    //设置一个为了在多线程的环境下线程安全
                    //改之前再确认这个值有没有被其他线程抢先修改，类似于CAS操作 cas加自旋，加个循环就是cas
                    underwater.eq(Article::getViewCounts, viewCounts);
                    // update article set view_count=100 where view_count=99 and id =111
                    //实体类加更新条件
                    int i=0;
                    if(map.containsKey(s) && redisTemplate.hasKey(s)){
                        i = mapper.update(articleupdate, underwater);
                    }
                    if(i>0){
                        map.remove(s);
                        redisTemplate.delete(s);
                    }
                }
        }
    }
}
